package com.example.shiro.config;

import com.example.shiro.realm.MyShiroRealm;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.Authorizer;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @ClassName ShiroConfig
 * @Description TODO shiro配置类
 * @Version 1.0
 */
@Configuration
public class ShiroConfig {

    /*
     * @Description //TODO 1. 创建 Realm（我们自定义的）
     * @Params []
     * @return com.example.shiro.realm.MyShiroRealm
     * @version 1.0
     **/
    @Bean
    public MyShiroRealm myShiroRealm() {
        return new MyShiroRealm();
    }

    @Bean
    public Authenticator authenticator(MyShiroRealm myShiroRealm) {
        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
        authenticator.setRealms(Collections.singletonList(myShiroRealm));
        return authenticator;
    }
    @Bean
    public SessionManager sessionManager() {
        // 创建默认的Web会话管理器
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置会话超时时间（毫秒），默认30分钟
        sessionManager.setGlobalSessionTimeout(1800000);
        // 是否定时检查会话
        sessionManager.setSessionValidationSchedulerEnabled(true);
        return sessionManager;
    }

    @Bean
    public Authorizer authorizer() {
        // 创建授权器
        return new ModularRealmAuthorizer();
    }
    /*
     * @Description //TODO 创建 SecurityManager，并注入 Realm
     * @Params [myShiroRealm]
     * @return org.apache.shiro.mgt.SecurityManager
     * @version 1.0
     **/
    @Bean
    public SecurityManager securityManager(MyShiroRealm myShiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm); // 设置 Realm
//        securityManager.setAuthenticator(authenticator);
        return securityManager;
    }
    /*
     * @Description //TODO 创建 ShiroFilterFactoryBean，用于定义拦截规则
     * @Params [securityManager]
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     * @version 1.0
     **/
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        // 配置登录和未授权页面
        shiroFilter.setLoginUrl("/login.html"); // 身份认证失败跳转页面
        shiroFilter.setUnauthorizedUrl("/index.html"); // 权限认证失败跳转页面

        // 配置拦截规则 (LinkedHashMap 保证顺序)
        // anon: 匿名访问，无需认证
        // authc: 需要认证才能访问
        // roles[manager]: 需要拥有 ‘manager’ 角色才能访问
        // perms[userAdd]: 需要拥有 ‘userAdd’ 权限才能访问
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 放行静态资源和登录页
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/toLogin", "anon");

        // 配置登出（Shiro 已经实现了 /logout 接口来处理登出逻辑）
        filterChainDefinitionMap.put("/logout", "logout");

        // 管理员页面需要 ‘manager’ 角色
        filterChainDefinitionMap.put("/admin/**", "roles[manager]");

        // 用户添加页面需要 ‘userAdd’ 权限
        filterChainDefinitionMap.put("/user/add", "perms[addUser]");

        // 其余所有请求都需要认证后才能访问
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilter;
    }
}
